package com.zhiwen.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhiwen.common.exception.BusinessException;
import com.zhiwen.domain.dto.VoteDTO;
import com.zhiwen.domain.entity.Answer;
import com.zhiwen.domain.entity.UserVote;
import com.zhiwen.mapper.UserVoteMapper;
import com.zhiwen.service.AnswerService;
import com.zhiwen.service.UserVoteService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

/**
 * 用户点赞服务实现类
 */
@Service
@RequiredArgsConstructor
public class UserVoteServiceImpl extends ServiceImpl<UserVoteMapper, UserVote> implements UserVoteService {

    private final AnswerService answerService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean voteAnswer(VoteDTO voteDTO) {
        // 获取当前登录用户
        Long userId = StpUtil.getLoginIdAsLong();

        // 检查回答是否存在
        Answer answer = answerService.getById(voteDTO.getAnswerId());
        if (answer == null) {
            throw new BusinessException("回答不存在");
        }

        // 不能给自己的回答点赞
        if (userId.equals(answer.getUserId())) {
            throw new BusinessException("不能给自己的回答点赞");
        }

        // 检查是否已经点赞
        LambdaQueryWrapper<UserVote> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserVote::getUserId, userId);
        wrapper.eq(UserVote::getAnswerId, voteDTO.getAnswerId());
        wrapper.eq(UserVote::getDeleted, 0);
        UserVote userVote = getOne(wrapper);

        int voteChange = 0;

        if (userVote != null) {
            // 已经点过赞，判断是否是相同的点赞类型
            if (userVote.getVoteType().equals(voteDTO.getVoteType())) {
                // 相同类型，取消点赞
                userVote.setDeleted(1);
                updateById(userVote);

                // 减少点赞数
                if (voteDTO.getVoteType() == 1) {
                    voteChange = -1; // 减少一个赞成票
                } else {
                    voteChange = 1; // 减少一个反对票，实际是增加一个赞成票
                }
            } else {
                // 不同类型，更新点赞类型
                userVote.setVoteType(voteDTO.getVoteType());
                userVote.setUpdateTime(LocalDateTime.now());
                updateById(userVote);

                // 更新点赞数
                if (voteDTO.getVoteType() == 1) {
                    voteChange = 2; // 从反对变为赞成，净增加2票
                } else {
                    voteChange = -2; // 从赞成变为反对，净减少2票
                }
            }
        } else {
            // 未点赞，创建点赞记录
            userVote = new UserVote();
            userVote.setUserId(userId);
            userVote.setAnswerId(voteDTO.getAnswerId());
            userVote.setVoteType(voteDTO.getVoteType());
            userVote.setCreateTime(LocalDateTime.now());
            userVote.setUpdateTime(LocalDateTime.now());
            userVote.setDeleted(0);
            save(userVote);

            // 更新点赞数
            if (voteDTO.getVoteType() == 1) {
                voteChange = 1; // 增加一个赞成票
            } else {
                voteChange = -1; // 增加一个反对票，实际是减少一个赞成票
            }
        }

        // 更新回答的点赞数
        answer.setVoteCount(answer.getVoteCount() + voteChange);
        answerService.updateById(answer);

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelVote(Long answerId) {
        // 获取当前登录用户
        Long userId = StpUtil.getLoginIdAsLong();

        // 检查回答是否存在
        Answer answer = answerService.getById(answerId);
        if (answer == null) {
            throw new BusinessException("回答不存在");
        }

        // 查询点赞记录
        LambdaQueryWrapper<UserVote> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserVote::getUserId, userId);
        wrapper.eq(UserVote::getAnswerId, answerId);
        wrapper.eq(UserVote::getDeleted, 0);
        UserVote userVote = getOne(wrapper);

        if (userVote == null) {
            return false;
        }

        // 逻辑删除点赞记录
        userVote.setDeleted(1);
        updateById(userVote);

        // 更新回答的点赞数
        int voteChange = userVote.getVoteType() == 1 ? -1 : 1;
        answer.setVoteCount(answer.getVoteCount() + voteChange);
        answerService.updateById(answer);

        return true;
    }

    @Override
    public Integer checkVoteStatus(Long answerId) {
        // 获取当前登录用户
        Long userId = StpUtil.getLoginIdAsLong();

        // 查询点赞记录
        LambdaQueryWrapper<UserVote> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserVote::getUserId, userId);
        wrapper.eq(UserVote::getAnswerId, answerId);
        wrapper.eq(UserVote::getDeleted, 0);
        UserVote userVote = getOne(wrapper);

        return userVote != null ? userVote.getVoteType() : null;
    }
}
